package org.example;

import java.util.Arrays;
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Scanner;

class UnionFind {
    int[] parent;

    UnionFind(int n) {
        parent = new int[n + 1];
        for (int i = 1; i < n + 1; i++) {
            parent[i] = i;
        }
    }

    private int find(int u) {
        if (parent[u] == u) {
            return u;
        }
        parent[u] = find(parent[u]);
        return parent[u];
    }

    public boolean tryJoin(int u, int v) {
        u = find(u);
        v = find(v);
        if (u == v) {
            return false;
        }
        parent[v] = u;
        return true;
    }
}

////并查集算法
//public class Main {
//    public static void main(String[] args) {
//        Scanner scanner = new Scanner(System.in);
//
//        int V = scanner.nextInt();
//        int E = scanner.nextInt();
//
//        PriorityQueue<int[]> queue = new PriorityQueue<>(Comparator.comparingInt(e -> e[2]));
//        for (int i = 0; i < E; i++) {
//            int u = scanner.nextInt();
//            int v = scanner.nextInt();
//            int w = scanner.nextInt();
//            queue.add(new int[]{u, v, w});
//        }
//
//        UnionFind unionFind = new UnionFind(V);
//        int count = 0;
//        int minDis = 0;
//        while (!queue.isEmpty()) {
//            int[] edge = queue.poll();
//            if (unionFind.tryJoin(edge[0], edge[1])) {
//                minDis += edge[2];
//                count++;
//                if (count == V - 1) {
//                    System.out.println(minDis);
//                    return;
//                }
//            }
//        }
//    }
//}

//prim算法
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        int V = scanner.nextInt();
        int E = scanner.nextInt();

        int[][] graph = new int[V + 1][V + 1];
        for (int i = 0; i < E; i++) {
            int u = scanner.nextInt();
            int v = scanner.nextInt();
            int w = scanner.nextInt();
            graph[u][v] = graph[v][u] = w;
        }

        boolean[] visited = new boolean[V + 1];
        int[] minDis = new int[V + 1];
        Arrays.fill(minDis, 10001);

        for (int i = 1; i <= V; i++) {          //循环n次，每次添加一个结点
            int cur = 0;
            int minVal = Integer.MAX_VALUE;
            for (int j = 1; j <= V; j++) {       //选取距离最小生成树最近的结点
                if (!visited[j] && minDis[j] < minVal) {
                    minVal = minDis[j];
                    cur = j;
                }
            }
            visited[cur] = true;

            for (int j = 1; j <= V; j++) {
                int w = graph[cur][j];
                if (w == 0) {
                    continue;
                }
                if (!visited[j] && w < minDis[j]) {
                    minDis[j] = w;
                }
            }
        }
        int totalDis = 0;
        for (int i = 2; i <= V; i++) {      //不计入第一个
            totalDis += minDis[i];
        }
        System.out.println(totalDis);
    }
}